package ga.cross;

import ga.GARun;
import ga.individuals.Individual;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import com.mathworks.toolbox.javabuilder.MWException;
import com.mathworks.toolbox.javabuilder.MWNumericArray;

public class Multiple implements CrossMethod {
	private int firstCrossPoint, sndCrossPoint;
	
	public Multiple() {
		Random crossPointGen = new Random(System.currentTimeMillis());
		int swapPoint;
		
		this.firstCrossPoint = crossPointGen.nextInt(GARun.networkWeightSize);
		
		do {
			this.sndCrossPoint = crossPointGen.nextInt(GARun.networkWeightSize);
		} while(this.sndCrossPoint == this.firstCrossPoint);
		
		if (firstCrossPoint > sndCrossPoint) {
			swapPoint = firstCrossPoint;
			firstCrossPoint = sndCrossPoint;
			sndCrossPoint = swapPoint;
		}
	}
	
	@Override
	public Collection<Individual> method(Collection<Individual> individuals) throws MWException {		
		/* El cruce se hace entre dos individuos */
		if (individuals.size() != 2) {
			return null;
		}
		List<Individual> listIndividuals = new LinkedList<Individual>(individuals);
		
		// prepara los hijos
		double[] childrenChromosomeOne = new double[GARun.networkWeightSize];
		double[] childrenChromosomeTwo = new double[GARun.networkWeightSize];
		
		// obtiene los padres a cruzar
		double[] chromosomeOne = (double[])listIndividuals.get(0).getIndividualValue().getDoubleData();
		double[] chromosomeTwo = (double[])listIndividuals.get(1).getIndividualValue().getDoubleData();
		
		// realiza el cruce
		for (int i = 0 ; i < GARun.networkWeightSize ; i++) {
			if (i < firstCrossPoint || i >= sndCrossPoint) {
				childrenChromosomeOne[i] = chromosomeOne[i];
				childrenChromosomeTwo[i] = chromosomeTwo[i];
			} else {
				childrenChromosomeOne[i] = chromosomeTwo[i];
				childrenChromosomeTwo[i] = chromosomeOne[i];
			}
		}
		
		List<Individual> offsprings = new LinkedList<Individual>();
		offsprings.add(new Individual(new MWNumericArray(childrenChromosomeOne)));
		offsprings.add(new Individual(new MWNumericArray(childrenChromosomeTwo)));
		return offsprings;
	}

}
